﻿#region Header
// ------------------------ Licence / Copyright ------------------------
// 
// ScrumTable for Scrum Meeting Support
// Copyright © HSR - Hochschule für Technik Rapperswil
// All Rights Reserved
// 
// Author:
//  Michael Gfeller Silvan Gehrig Patrick Boos
// 
// ---------------------------------------------------------------------
#endregion

#region Usings

using System;
using System.Collections.Generic;

#endregion

namespace ScrumTable.Common.Collections
{
    /// <summary>
    /// Specifies the builder facilities for ValueChain&lt;T&gt; objects.
    /// </summary>
    public class ValueChainBuilder<T>
        where T : class
    {
        #region Declarations
        //--------------------------------------------------------------------
        // Declarations
        //--------------------------------------------------------------------

        private readonly IList<T> _keys;

        #endregion

        #region Properties
        //--------------------------------------------------------------------
        // Properties
        //--------------------------------------------------------------------

        /// <summary>
        /// Gets the value at the given chain index.
        /// </summary>
        /// <param name="index">Index of the value to retrieve.</param>
        /// <returns>Returns the retrieved value.</returns>
        public T this[int index]
        {
            get
            {
                PreCondition.AssertInRange(-1, _keys.Count, index, "index");
                return _keys[index];
            }
        }

        /// <summary>
        /// Gets the number of values stored in the current collection.
        /// </summary>
        public int Count
        {
            get { return _keys.Count; }
        }

        /// <summary>
        /// Returns true if the current value chain is empty.
        /// </summary>
        public bool IsEmpty
        {
            get { return (Count == 0); }
        }

        /// <summary>
        /// Gets the top value. This represents the value on the right side of the chain.
        /// </summary>
        public T Top
        {
            get { return (_keys.Count > 0) ? _keys[_keys.Count - 1] : ValueChain<T>.GetDefaultValue(); }
        }

        /// <summary>
        /// Gets the bottom value. This represents the value on the left side of the chain.
        /// </summary>
        public T Bottom
        {
            get { return (_keys.Count > 0) ? _keys[0] : ValueChain<T>.GetDefaultValue(); }
        }

        #endregion

        #region Constructors / Destructor
        //--------------------------------------------------------------------
        // Constructors / Destructor
        //--------------------------------------------------------------------

        /// <summary>
        /// Creates a new ValueChainBuilder instance.
        /// </summary>
        public ValueChainBuilder()
            : this(1)
        {
        }

        /// <summary>
        /// Creates a new ValueChainBuilder instance.
        /// </summary>
        /// <param name="valueEntries">Specifies the number of chain entries.</param>
        public ValueChainBuilder(int valueEntries)
        {
            _keys = new List<T>(valueEntries);
        }

        #endregion

        #region Methods
        //--------------------------------------------------------------------
        // Methods
        //--------------------------------------------------------------------

        /// <summary>
        /// Checks whether the current builder contains the specified key.
        /// </summary>
        /// <param name="toCheck">Specifies the key to check.</param>
        /// <returns>Returns true if the given key is contained in the current builder.</returns>
        public bool Contains(T toCheck)
        {
            return _keys.Contains(toCheck);
        }

        /// <summary>
        /// Creates a new chain instance from the stored values.
        /// </summary>
        /// <returns></returns>
        public ValueChain<T> ToChain()
        {
            return new ValueChain<T>(_keys);
        }

        /// <summary>
        /// Adds a value on the top of the chain. This represents the value on the right side of the chain.
        /// </summary>
        public void AddTop(T toAdd)
        {
            PreCondition.AssertNotNull(toAdd, "toAdd");

            _keys.Add(toAdd);
        }

        /// <summary>
        /// Adds a value on the bottom of the chain. This represents the value on the left side of the chain.
        /// </summary>
        public void AddBottom(T toAdd)
        {
            PreCondition.AssertNotNull(toAdd, "toAdd");

            _keys.Insert(0, toAdd);
        }

        #endregion

        #region Events
        //--------------------------------------------------------------------
        // Events
        //--------------------------------------------------------------------

        #endregion
    }
}